package com.gopay.bis.service.bank.sms;

import com.gopay.bis.dao.payconfig.BisExpaySmsSendLogDAO;
import com.gopay.bis.manager.bank.payconfig.SmsSupportService;
import com.gopay.common.constants.bank.SmsSendSourceConstants;
import com.gopay.common.constants.cust.SMSType;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.cps.manager.order.CpsGeneralMainOrderQueryManager;
import com.gopay.common.domain.bank.ExPayBaseMessage;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.domain.ep.EpCardStatus;
import com.gopay.common.domain.log.BisExpaySmsSendLog;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.cps.expresspay.EpBankCardRemoteService;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;

import net.spy.memcached.compat.log.Logger;
import net.spy.memcached.compat.log.LoggerFactory;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * bis发送平台手机短信验证码
 * 
 * @author zhengxue
 * 
 */
public class SmsSupportController {
    private static Logger logger = LoggerFactory.getLogger(SmsSupportController.class);

    @Resource(name = "cpsGeneralMainOrderQueryManager")
    private CpsGeneralMainOrderQueryManager mainOrderQuery;

    @Resource(name = "smsSupportService")
    private SmsSupportService smsSupportService;

    @Resource(name = "epBankCardService")
    protected EpBankCardRemoteService epBankCardService;
    
    @Resource(name = "bisExpaySmsSendLogDAO")
    private BisExpaySmsSendLogDAO bisExpaySmsSendLogDAO;

    
    /** 
     * 查询该订单是否允许发送短信
     * @param baseMsg
     * @return 
     */
    public Map<String ,String> querySendSMS(ExPayBaseMessage baseMsg){
        Map<String ,String> resMap = new HashMap<String ,String>();
        if(0 == baseMsg.getSenMaxCount()){
            resMap.put("sendCount", "0");
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6092);
            resMap.put("retMsg", "发送短信最大次数为0");
            //falg 为01，不满足发短信条件
            resMap.put("flag", "01");
            return resMap;
        }
        if (0 == baseMsg.getFailMaxCount()) {
            resMap.put("sendCount", "0");
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6097);
            resMap.put("retMsg", "验证短信失败最大次数为0");
            resMap.put("flag", "01");
            return resMap;
        }
        // 发送短信最大次数网关传送，按orderId查询
        int sendCount = smsSupportService.checkSendSmsCont(baseMsg.getOrderId());
        if ((sendCount > baseMsg.getSenMaxCount() - 1)) {
            resMap.put("sendCount", String.valueOf(sendCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6094);
            resMap.put("retMsg", "获取次数超限，获取失败");
            resMap.put("flag", "01");
            return resMap;
        }
        // 查询该卡状态
        boolean isFreeze = epBankCardService.isFreezeCardNo(baseMsg.getCardNo());

        // 短信失败最大次数网关传送，按orderId查询
        int failCount = smsSupportService.checkFailSmsCount(baseMsg.getOrderId());
        if ((failCount > baseMsg.getFailMaxCount() - 1) && !isFreeze) {
            resMap.put("sendCount", String.valueOf(sendCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6095);
            resMap.put("retMsg", "错误次数超限，获取失败");
            resMap.put("flag", "01");
            return resMap;
        }

        if (isFreeze) {
            resMap.put("sendCount", String.valueOf(sendCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6100);
            resMap.put("retMsg", "当日错误次数超限，该卡已被锁定");
            resMap.put("flag", "01");
            return resMap;
        }
        resMap.put("sendCount", String.valueOf(sendCount));
        resMap.put("flag", "00");
        return resMap;                
    }

    /**
     * 发送
     * @param baseMsg
     * @return
     */
    public Map<String, String> sendSMS(ExPayBaseMessage baseMsg) {
        Map<String, String> resMap = new HashMap<String, String>();
        if (0 == baseMsg.getSenMaxCount()) {
            resMap.put("sendCount", "0");
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6092);
            resMap.put("retMsg", "发送短信最大次数为0");
            return resMap;
        }
        if (0 == baseMsg.getFailMaxCount()) {
            resMap.put("sendCount", "0");
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6097);
            resMap.put("retMsg", "验证短信失败最大次数为0");
            return resMap;
        }
        // 发送短信最大次数网关传送，按orderId查询
        int sendCount = smsSupportService.checkSendSmsCont(baseMsg.getOrderId());
        if ((sendCount > baseMsg.getSenMaxCount() - 1)) {
            resMap.put("sendCount", String.valueOf(sendCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6094);
            resMap.put("retMsg", "获取次数超限，获取失败");
            return resMap;
        }

        // 查询该卡状态
        boolean isFreeze = epBankCardService.isFreezeCardNo(baseMsg.getCardNo());

        // 短信失败最大次数网关传送，按orderId查询
        int failCount = smsSupportService.checkFailSmsCount(baseMsg.getOrderId());
        if ((failCount > baseMsg.getFailMaxCount() - 1) && !isFreeze) {
            resMap.put("sendCount", String.valueOf(sendCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6095);
            resMap.put("retMsg", "错误次数超限，获取失败");
            return resMap;
        }

        if (isFreeze) {
            resMap.put("sendCount", String.valueOf(sendCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6100);
            resMap.put("retMsg", "当日错误次数超限，该卡已被锁定");
            return resMap;
        }
        boolean res = smsSupportService.sendSMS(baseMsg);
        if (res) {
            resMap.put("sendCount", String.valueOf(sendCount + 1));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6102);
            resMap.put("retMsg", "短信发送成功");
            return resMap;
        } else {
            resMap.put("sendCount", String.valueOf(sendCount + 1));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6096);
            resMap.put("retMsg", "获取短信验证码失败，请稍后再试");
            return resMap;
        }
    }
    
    /**
     * 新增发送短信记录的日志
     * 
     * @param baseMsg
     * @return
     */
    public Map<String, String> buildSendLog(ExPayBaseMessage baseMsg, int sendCount) {
        Map<String, String> resMap = new HashMap<String, String>();
        BisExpaySmsSendLog log = new BisExpaySmsSendLog();
        Date date = new Date();
        log.setMobileNum(baseMsg.getMediaId());
        log.setModuleId(SMSType.CASHIER_SMS_SEND.value);
        log.setOrderId(baseMsg.getOrderId());
        log.setCardNo(baseMsg.getCardNo());
        if(StringUtils.isNotEmpty(baseMsg.getBankOrderId())){
            log.setRemark(baseMsg.getBankOrderId());
        }
        log.setOperateSource(SmsSendSourceConstants.SEND_SOURCE_BANK);
        log.setCreatedTime(date);
        bisExpaySmsSendLogDAO.save(log);
        resMap.put("sendCount", String.valueOf(sendCount+1));
        resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6102);
        resMap.put("retMsg", "短信发送成功");
        return resMap;
    }
    
    /**
     * 新增校验失败的日志
     * 
     * @param baseMsg
     * @return
     */
    public Map<String, String> buildCheckLog(ExPayBaseMessage baseMsg, int failCount) {
        Map<String, String> resMap = new HashMap<String, String>();
        BisExpaySmsSendLog log = new BisExpaySmsSendLog();
        Date date = new Date();
        log.setMobileNum(baseMsg.getMediaId());
        log.setModuleId(SMSType.CASHIER_SMS_ERROR.value);
        log.setOrderId(baseMsg.getOrderId());
        log.setCardNo(baseMsg.getCardNo());
        log.setOperateSource(SmsSendSourceConstants.CHECK_SOURCE_BANK);
        log.setCreatedTime(date);
        bisExpaySmsSendLogDAO.save(log);
        resMap.put("failCount", String.valueOf(failCount + 1));
        resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6101);
        resMap.put("retMsg", "短信验证码错误，您还有" + (baseMsg.getFailMaxCount() - failCount - 1) + "次机会");
        return resMap;

    }
    
    /** 
     * 查询是否允许校验短信
     * @param baseMsg
     * @return 
     */
    public Map<String, String> queryCheckSMS(ExPayBaseMessage baseMsg) {
        Map<String, String> resMap = new HashMap<String, String>();
        if (0 == baseMsg.getFailMaxCount()) {
            resMap.put("failCount", "0");
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6097);
            resMap.put("retMsg", "验证短信失败最大次数为0");
            resMap.put("flag", "01");
            return resMap;
        }
     
        int failCount = smsSupportService.checkFailSmsCount(baseMsg.getOrderId());
        
        boolean isFreeze = epBankCardService.isFreezeCardNo(baseMsg.getCardNo());
        if (isFreeze) {
            resMap.put("failCount", String.valueOf(failCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6100);
            resMap.put("retMsg", "当日错误次数超限，该卡已被锁定");
            resMap.put("flag", "01");
            return resMap;
        }        
        if ((failCount > baseMsg.getFailMaxCount() - 1)) {
            int sameOrderCardFailCount = smsSupportService.checkCardFailSmsCount(baseMsg.getOrderId(),
                    baseMsg.getCardNo());
            if (sameOrderCardFailCount == baseMsg.getFailMaxCount()) {
                resMap.put("failCount", String.valueOf(failCount));
                resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6100);
                resMap.put("retMsg", "当日错误次数超限，该卡已被锁定");
                resMap.put("flag", "01");
                return resMap;
            } else {
                resMap.put("failCount", String.valueOf(failCount));
                resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6099);
                resMap.put("retMsg", "错误次数超限，无法提交");
                resMap.put("flag", "01");
                return resMap;
            }
        }  
        
        resMap.put("failCount", String.valueOf(failCount));
        resMap.put("flag", "00");        
        return resMap;
    }


    /**
     * 验证
     * @param baseMsg
     * @return
     */
    public Map<String, String> checkSMS(ExPayBaseMessage baseMsg) {
        Map<String, String> resMap = new HashMap<String, String>();
        if (0 == baseMsg.getFailMaxCount()) {
            resMap.put("failCount", "0");
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6097);
            resMap.put("retMsg", "验证短信失败最大次数为0");
            return resMap;
        }
     
        int failCount = smsSupportService.checkFailSmsCount(baseMsg.getOrderId());
        
        boolean isFreeze = epBankCardService.isFreezeCardNo(baseMsg.getCardNo());
        if (isFreeze) {
            resMap.put("failCount", String.valueOf(failCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6100);
            resMap.put("retMsg", "当日错误次数超限，该卡已被锁定");
            return resMap;
        }        
        if ((failCount > baseMsg.getFailMaxCount() - 1)) {
            int sameOrderCardFailCount = smsSupportService.checkCardFailSmsCount(baseMsg.getOrderId(),
                    baseMsg.getCardNo());
            if (sameOrderCardFailCount == baseMsg.getFailMaxCount()) {
                resMap.put("failCount", String.valueOf(failCount));
                resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6100);
                resMap.put("retMsg", "当日错误次数超限，该卡已被锁定");
                return resMap;
            } else {
                resMap.put("failCount", String.valueOf(failCount));
                resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6099);
                resMap.put("retMsg", "错误次数超限，无法提交");
                return resMap;
            }
        }                
        boolean checkRes = smsSupportService.checkSMS(baseMsg);
        if (checkRes) {
            resMap.put("failCount", String.valueOf(failCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6091);
            resMap.put("retMsg", "短信验证码输入正确");
            return resMap;
        } else {
            resMap.put("failCount", String.valueOf(failCount + 1));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6098);
            resMap.put("retMsg", "短信验证码错误，您还有" + (5 - failCount - 1) + "次机会");
            return resMap;
        }
    }

    /**
     * 冻卡操作
     * 
     * @param baseMsg
     * @return
     */
    public Map<String, String> freezeCard(ExPayBaseMessage baseMsg) {
        Map<String, String> resMap = new HashMap<String, String>();
        // 校验失败后，调用cps进行冻卡操作
        int failCount = smsSupportService.checkFailSmsCount(baseMsg.getOrderId());
        EpCardStatus epCardStatus = epBankCardService.errAccum4SMS(baseMsg.getCardNo());
        if (EpCardStatus.STATUS_FREEZE.equals(epCardStatus.getStatus())) {
            resMap.put("failCount", String.valueOf(failCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6100);
            resMap.put("retMsg", "当日错误次数超限，该卡已被锁定");
            return resMap;
        } else if (failCount == baseMsg.getFailMaxCount()) {
            resMap.put("failCount", String.valueOf(failCount));
            resMap.put("resCode", ProcCodeConstants.PROC_CODE_100E6099);
            resMap.put("retMsg", "错误次数超限，无法提交");
            return resMap;
        }
        return null;
    }

    /**
     * 鉴权前，先确认能发短信失败次数，验短信失败次数是否超限，卡是否冻结
     * 
     * @param baseMsg
     * @return
     */

    /**
     * 鉴权前，先确认卡是否冻结,短信失败次数、验短信失败次数是否超限，
     * 
     * @param baseMsg
     * @throws GopayException
     */
    public void checkCertification(ExPayBaseMessage baseMsg) throws GopayException {

        // 查询该卡状态
        boolean isFreeze = epBankCardService.isFreezeCardNo(baseMsg.getCardNo());
        if (isFreeze) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E6100);
        }

        int sendMaxCount = baseMsg.getSenMaxCount() == 0 ? 5 : baseMsg.getSenMaxCount();
        int sendCount = smsSupportService.checkSendSmsCont(baseMsg.getOrderId());
        if (sendCount > sendMaxCount - 1) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E6094);
        }

        int failMaxCount = baseMsg.getFailMaxCount() == 0 ? 5 : baseMsg.getFailMaxCount();
        int failCount = smsSupportService.checkFailSmsCount(baseMsg.getOrderId());
        if (failCount > failMaxCount - 1) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E6095);
        }

    }

    /**
     * @param orderId
     * @param nullException
     *            - true:如果CpsGenMainOrder为null，抛出异常；false:
     *            如果CpsGenMainOrder为null，返回null
     * @throws GopayException
     */
    protected CpsGenMainOrder getMainOrder(String orderId, boolean nullException) throws GopayException {
        CpsGenMainOrder order = null;
        if (StringUtils.isBlank(orderId)) {
            // 如果orderId为空，需要返回null；
            logger.error("查询CpsGenMainOrder，订单号orderId为空！ ");
        } else {
            order = mainOrderQuery.get(orderId);
        }
        if (nullException) {
            if (null == order) {
                logger.error("找不到订单！order not exits! orderId=" + orderId);
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E5041);
            } else {
                return order;
            }
        }
        return order;
    }
}
